/**
* @file		Panel.Game.ixx
* @brief	游戏场景界面
*
*
* @version	1.0
* @author	lveyou
* @date		22-03-08
*
*/

export module Panel.Game;

import DND;

import DefOrder;
import DefVar;
import ResMgr;
import Node;
import Facility;
import Database;
import Medium.PanelGame;
import GroupLocation;
import Facility;
import FacilityLocation;
import WorldTime;
import Area;
import World;

export class PanelGame : public UI::Panel
{
public:
	PanelGame();

	void _init_group_age();

	void _init_group_editor();

	void _init_group_area();

	void _init_group_terrain();
	//更新 节点界面
	void RefreshNode(Node* node);
	//更新 设施界面
	void RefreshFacility(Facility* fac, bool to_ui);
	//更新 时间界面
	void RefreshAge(WorldTime& world_time, bool to_ui);
	//更新 区域界面
	void RefreshArea(Area* area, bool to_ui);

	//手动绘制界面
	void RunHand(const LogicType& lt);

	MediumPanelGame GetMedium()
	{
		return {
			_editor._grpTerrain->GetIndexOpen(),
			_editor._grpSize->GetIndexOpen(),
			_editor._grpMenu->GetIndexCilck(),
			_editor._grpGrid->GetIndexOpen() == 0,
			(natural)atoi(_editor._edtGrid->GetEditBox()->GetString().c_str()),
			_editor._grpEditWater->GetIndexOpen() == 0,
			_editor._grpNewNode->GetIndexOpen() == 0,
			_editor._grpFacility->GetIndexOpen(),
			_editor._grpFacility->GetIndexOpen() + 1 == _editor._grpFacility->GetSize(),
			_editor._lstImportLocation->IsLoseFocus() ? _editor._lstImportLocation->GetIndex() : -1,
			_editor._grpArea->GetIndexOpen(),
			_editor._grpRegime->GetIndexOpen()
		};
	}

private:
	//地形信息
	struct GroupTerrain
	{
		UI::Group* _grp;
		UI::Group* _grpRight;
		UI::Text* _txt[4];
	}_terrain;

	bool _bNode;	//显示节点界面
	bool _bFacility;//显示设施界面
	bool _bArea;	//显示区域界面
	natural _facilityClassID;

	//编辑界面 
	struct Editor
	{
		//----------------------terrain--------------------------------
		UI::Group* _grp;//左侧文本
		UI::Group* _grpTerrain;//地形刷子
		UI::Group* _grpSize;//刷子大小

		UI::Group* _grpEditWater;//编辑水域
		UI::Group* _grpNewNode;//新建节点
		UI::Group* _grpGrid;//网格设置
		UI::EditBoxNormal* _edtGrid;

		UI::Group* _grpFacility;//设施
		UI::Group* _grpImportLocation;//载入定居
		UI::ListBox* _lstImportLocation;
		UI::Group* _grpArea;//区域

		UI::Group* _grpRegime;//势力
		//---------------------------menu----------------------------
		UI::Group* _grpMenu;//菜单

	}_editor;

	//设施信息
	struct GroupFacility
	{
		void Init(Panel* panel)
		{
			_location.Init(panel);
		}
		
	public:
		GroupLocation _location;
	}_facility;

	//区域面板
	struct GroupArea
	{
		UI::Group* _grp;//左侧文本
		UI::Group* _grpRight;//右侧内容
		UI::EditBoxNormal* _edtName;//名字
		UI::ListBox* _lstColor;//颜色
	}_area;

	//时间面板
	struct GroupAge
	{
		UI::Group* _grp;

		UI::Text* _txtYear;
		UI::Text* _txtMonth;//月日
		UI::ListBox* _lst;
	}_age;

};


module :private;



PanelGame::PanelGame()
{
	SetOrder(DefOrder::UI);


	_init_group_terrain();
	_init_group_area();
	_init_group_editor();

	_facility.Init(this);

	//age
	_init_group_age();

}

void PanelGame::_init_group_age()
{
	_age._grp = CreateGroup({ 0, 0 }, { 0.5, 0.0 },
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });

	{
		auto* txt = UI::Text::Create(g_res->CreateTextAge(false));
		txt->SetElementData(Horizontal::CENTER, Vertical::TOP);
		_age._grp->Add(&txt->_cpts);

		_age._txtYear = txt;
	}

	{
		auto* txt = UI::Text::Create(g_res->CreateTextAge(true));
		txt->SetElementData(Horizontal::CENTER, Vertical::TOP);
		_age._grp->Add(&txt->_cpts);

		_age._txtMonth = txt;
	}

	{
		UI::ListBox* lst = g_res->CreateListBox();
		lst->SetElementData(Horizontal::CENTER, Vertical::TOP);
		for (auto& iter : g_db->GetAgeRef())
		{
			lst->Add(iter._name);
		}
		_age._grp->Add(&lst->_cpts);

		_age._lst = lst;
	}

	_age._grp->SetBackgroud("bg", DefVar::UI_EXTRA_AGE, DefVar::UI_OFFSET_AGE);
}

void PanelGame::_init_group_editor()
{
	_editor._grp = CreateGroup({ DefVar::UI_SX_LEFT, 0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });
	{
		size_t size = g_lang->GetTagSize("editor");
		for (size_t i = 0; i < size; ++i)
		{
			auto* txt = UI::Text::Create(g_res->CreateTextTitle());
			txt->SetLang("editor", std::to_string(i));
			_editor._grp->Add(&txt->_cpts);
			if (i == 0)
			{//地形用两行
				auto* txt = UI::Text::Create(g_res->CreateTextTitle());
				_editor._grp->Add(&txt->_cpts);
			}
		}
	}

	_editor._grp->SetBackgroud("bg", { DefVar::UI_W, DefVar::UI_H }, DefVar::UI_OFFSET_BG);

	//editor terrain（n个换行）
	_editor._grpTerrain = CreateGroup({ DefVar::UI_DX_0, 0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, DefVar::UI_DY_0}, Locator::Layout::ROW, 6 });
	{
		size_t size = g_lang->GetTagSize("terrain");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();
			btn->SetMode(UI::Control::Mode::RADIO);

			if (i == size - 1)
				btn->SetLang("terrain", "delete");
			else
				btn->SetLang("terrain", std::to_string(i));

			_editor._grpTerrain->Add(&btn->_cpts);
		}
	}

	//editor size
	_editor._grpSize = CreateGroup({ DefVar::UI_DX_0, 2 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		size_t size = g_lang->GetTagSize("editor_size");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();
			btn->SetMode(UI::Control::Mode::RADIO);
			btn->SetLang("editor_size", std::to_string(i));
			_editor._grpSize->Add(&btn->_cpts);
		}
	}

	//editor edit water
	_editor._grpEditWater = CreateGroup({ DefVar::UI_DX_0, 3 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		auto* swt = g_res->CreateSwitch();
		swt->SetOpen(true);
		_editor._grpEditWater->Add(&swt->_cpts);
	}

	//editor new node
	_editor._grpNewNode = CreateGroup({ DefVar::UI_DX_0, 4 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		auto* swt = g_res->CreateSwitch();
		swt->SetOpen(true);
		_editor._grpNewNode->Add(&swt->_cpts);
	}

	//editor grid
	_editor._grpGrid = CreateGroup({ DefVar::UI_DX_0, 5 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		auto* swt = g_res->CreateSwitch();
		swt->SetOpen(true);
		_editor._grpGrid->Add(&swt->_cpts);

		auto* edt = g_res->CreateEditBox();
		_editor._grpGrid->Add(&edt->_cpts);

		_editor._edtGrid = edt;
		_editor._edtGrid->GetEditBox()->SetString(std::to_string(100));
	}

	//editor 设施
	_editor._grpFacility = CreateGroup({ DefVar::UI_DX_0, 6 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		size_t size = g_lang->GetTagSize("facility");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();

			btn->SetMode(UI::Control::Mode::RADIO);
			if (i == size - 1)
				btn->SetLang("terrain", "delete");
			else
				btn->SetLang("facility", std::to_string(i));

			_editor._grpFacility->Add(&btn->_cpts);
		}
	}

	//editor 导入定居
	_editor._grpImportLocation = CreateGroup({ DefVar::UI_DX_0, 7 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });

	{
		UI::ListBox* lst = g_res->CreateListBox();
		lst->Add("现代中国");
		_editor._grpImportLocation->Add(&lst->_cpts);

		_editor._lstImportLocation = lst;
	}

	//editor area
	_editor._grpArea = CreateGroup({ DefVar::UI_DX_0, 8 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });
	{
		size_t size = g_lang->GetTagSize("editor_area");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();
			btn->SetMode(UI::Control::Mode::RADIO);
			btn->SetLang("editor_area", std::to_string(i));

			_editor._grpArea->Add(&btn->_cpts);
		}
	}

	//editor regime
	_editor._grpRegime = CreateGroup({ DefVar::UI_DX_0, 9 * DefVar::UI_DY_0 }, DefVar::UI_LEFT_0,
		Locator{ {}, {DefVar::UI_DX_BUTTON_TEXT, 0}, Locator::Layout::ROW });
	{
		size_t size = g_lang->GetTagSize("editor_regime");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();
			btn->SetMode(UI::Control::Mode::RADIO);
			btn->SetLang("editor_area", std::to_string(i));

			_editor._grpRegime->Add(&btn->_cpts);
		}
	}

	//editor menu
	_editor._grpMenu = CreateGroup({ 200, 0 }, {},
		Locator{ {}, {DefVar::UI_DX_MENU, 0}, Locator::Layout::ROW });

	{
		size_t size = g_lang->GetTagSize("editor_menu");
		for (size_t i = 0; i < size; ++i)
		{
			auto* btn = g_res->CreateButtonText();
			btn->SetLang("editor_menu", std::to_string(i));
			btn->SetElementData(Horizontal::LEFT, Vertical::TOP);
			_editor._grpMenu->Add(&btn->_cpts);
		}
	}

	_editor._grpMenu->SetBackgroud("bg", DefVar::UI_EXTRA_MENU, DefVar::UI_OFFSET_BG);
}

void PanelGame::_init_group_area()
{
	constexpr real Y = 0.75;
	_area._grp = CreateGroup({ DefVar::UI_SX_RIGHT, 0 }, { 1.0, Y },
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });
	_area._grp->SetAutoRun(false);

	{
		size_t size = g_lang->GetTagSize("ui_area");
		for (size_t i = 0; i < size; ++i)
		{
			auto* txt = UI::Text::Create(g_res->CreateTextTitle());
			txt->SetLang("ui_area", std::to_string(i));
			_area._grp->Add(&txt->_cpts);
		}
	}
	_area._grp->SetBackgroud("bg", { DefVar::UI_W, DefVar::UI_H }, DefVar::UI_OFFSET_BG);

	//area right
	_area._grpRight = CreateGroup({ DefVar::UI_SX_RIGHT + DefVar::UI_DX_0, 0 }, { 1.0, Y },
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });
	_area._grpRight->SetAutoRun(false);

	{
		//0 名称
		auto* edt = g_res->CreateEditBox();
		_area._grpRight->Add(&edt->_cpts);

		_area._edtName = edt;
	}

	{
		//1 颜色 加入区域可用颜色
		UI::ListBox* lst = g_res->CreateListBox();
		for(size_t i = 0; true; ++i)
		{
			string str = "area_" + to_string(i);
			optional<Color> color = g_factory->GetColorCheck(str);
			if (color.has_value())
			{
				lst->Add(format("#{}        ", i));
				Text* txt = lst->GetText(i);
				txt->SetBackground(true, color.value());
				txt->SetColor(colorInverse(as_const(color.value())));
			}
			else
				break;
		}
		_area._grpRight->Add(&lst->_cpts);

		_area._lstColor = lst;
	}
}

void PanelGame::_init_group_terrain()
{
	_terrain._grp = CreateGroup({ DefVar::UI_SX_RIGHT, 0 }, { 1.0, 0.25 },
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });
	_terrain._grp->SetAutoRun(false);

	{
		size_t size = g_lang->GetTagSize("ui_terrain");
		for (size_t i = 0; i < size; ++i)
		{
			auto* txt = UI::Text::Create(g_res->CreateTextTitle());
			txt->SetLang("ui_terrain", std::to_string(i));
			_terrain._grp->Add(&txt->_cpts);
		}
	}

	_terrain._grp->SetBackgroud("bg", { DefVar::UI_W, DefVar::UI_H }, DefVar::UI_OFFSET_BG);

	//terrain right
	_terrain._grpRight = CreateGroup({ DefVar::UI_SX_RIGHT + DefVar::UI_DX_0, 0 }, DefVar::UI_RIGHT_0,
		Locator{ {}, {0, DefVar::UI_DY_0}, Locator::Layout::COLUMN });
	_terrain._grpRight->SetAutoRun(false);

	{
		size_t size = g_lang->GetTagSize("ui_terrain");
		for (size_t i = 0; i < size; ++i)
		{
			auto* txt = UI::Text::Create(g_res->CreateTextNormal());
			_terrain._grpRight->Add(&txt->_cpts);

			_terrain._txt[i] = txt;
		}
	}
}

void PanelGame::RefreshNode(Node* node)
{
	if (node == nullptr)
	{
		_bNode = false;
		return;
	}

	_bNode = true;

	const Node::SL& sl = node->GetSL();
	Node::TP& tp = node->GetTpRef();

	Point xy = sl._xy;
	Vector2 l = toVector2(Xy2Ll(xy)) * DefVar::L_PER_NODE;

	_terrain._txt[0]->SetString(
		format("{}, {} ({:.1f}, {:.1f})",
			xy[0], xy[1], l[0], l[1]));

	_terrain._txt[1]->SetString(std::to_string(GetNodeAcreage(sl._xy)));
	_terrain._txt[2]->SetString(lang("terrain", std::to_string(sl._typeTerrain)));

	//设置所属区域
	Area* area = nullptr;
	if (tp._uidArea != -1)
		area = g_world->GetArea(tp._uidArea);
	if(area)
		_terrain._txt[3]->SetString(area->GetName());
	else
		_terrain._txt[3]->SetString(lang("area", "none"));

	//更新位置
	/*for (auto& iter : _terrain._txt)
	{
		_terrain._grpRight->_on_change_element_data(&iter->_cpts);
	}*/
}

void PanelGame::RefreshFacility(Facility* fac, bool to_ui)
{
	if (fac == nullptr)
	{
		_bFacility = false;
		return;
	}
	_bFacility = true;
	_facilityClassID = fac->GetSL()._type;

	AnyType& data = fac->GetData();
	if (FacilityLocation* location = data.Cast<FacilityLocation>())
	{
		_facility._location.Refresh(*location, to_ui);
	}
	else
	{

	}
}

void PanelGame::RefreshAge(WorldTime& world_time, bool to_ui)
{
	if (to_ui)
	{
		//这里需要假设下拉框不存在
		zahlen y = (zahlen)(int)world_time.GetYear();
		//时代名
		string str_age_name = g_db->GetAgeName(y);
		//公元前 或 公元
		string str_year = y < 0 ? "公元前" : "公元";
		//公元前200年（时代名）
		string str_age = format("{}{}年（{}）",
			str_year, abs(y), str_age_name);
		_age._txtYear->SetString(str_age);

		//月与日
		string str_month = format("{}月{}日", (unsigned)world_time.GetMonth(), (unsigned)world_time.GetDay());
		_age._txtMonth->SetString(str_month);
	}
	else
	{
		if (_age._lst->IsLoseFocus())
		{
			Point range = g_db->GetAgeRange(_age._lst->GetIndex());

			//world_time.SetYear(ChronoYear{ (int)range[0] });
			world_time.Set(ChronoYear{ (int)range[0] }, 1m, 1d);
		}

	}
}

void PanelGame::RefreshArea(Area* area, bool to_ui)
{
	if (area == nullptr)
	{
		_bArea = false;
		return;
	}
	if (to_ui)
	{
		_bArea = true;
		UI::EditBox* edt = _area._edtName->GetEditBox();
		if (!edt->IsFocus())
		{
			edt->SetString(area->GetSL()._name);
		}
		if (!_area._lstColor->IsFocus())
		{
			_area._lstColor->SetIndex(area->GetSL()._idColor);
		}
	}
	else
	{
		UI::EditBox* edt = _area._edtName->GetEditBox();
		Area::SL& sl = area->GetSlRef();
		if (edt->IsLoseFocus())
		{
			sl._name = edt->GetString();
			area->RefreshUI(Area::Refresh::NAME);
		}
		if (_area._lstColor->IsLoseFocus())
		{
			sl._idColor = _area._lstColor->GetIndex();
			area->RefreshUI(Area::Refresh::AREA);
		}
	}
}

void PanelGame::RunHand(const LogicType& lt)
{
	if (_bNode)
	{
		_terrain._grp->Run(lt);
		_terrain._grpRight->Run(lt);
	}

	if (_bFacility)
	{
		if (_facilityClassID == FacilityLocation::GetClassID())
		{
			_facility._location.Run(lt);
		}
	}

	if (_bArea)
	{
		_area._grp->Run(lt);
		_area._grpRight->Run(lt);
	}

	if (lt.IsRender())
	{

	}
}
